<html>
<head><meta charset="utf-8"><title>primitive reference (Clone) doc wrong? · t-libs · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/index.html">t-libs</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/primitive.20reference.20(Clone).20doc.20wrong.3F.html">primitive reference (Clone) doc wrong?</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="239635843"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/primitive%20reference%20%28Clone%29%20doc%20wrong%3F/near/239635843" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/primitive.20reference.20(Clone).20doc.20wrong.3F.html#239635843">(May 20 2021 at 18:11)</a>:</h4>
<p><a href="https://doc.rust-lang.org/std/primitive.reference.html#trait-implementations-1">https://doc.rust-lang.org/std/primitive.reference.html#trait-implementations-1</a><br>
seems wrong about <code>Clone</code> bypassing the implementation on <code>T</code> for <code>(&amp;T).clone()</code><br>
counterexample: <a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=eabe414c721b8f7e59b94a77d6d6883b">https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=eabe414c721b8f7e59b94a77d6d6883b</a><br>
does anyone have a pointer to an explanation of how the doc would be correct?</p>



<a name="239641404"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/primitive%20reference%20%28Clone%29%20doc%20wrong%3F/near/239641404" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Giacomo Stevanato <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/primitive.20reference.20(Clone).20doc.20wrong.3F.html#239641404">(May 20 2021 at 18:52)</a>:</h4>
<p>In <code>let _z: A = y.clone();</code> you still have autoderef</p>



<a name="239642064"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/primitive%20reference%20%28Clone%29%20doc%20wrong%3F/near/239642064" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/primitive.20reference.20(Clone).20doc.20wrong.3F.html#239642064">(May 20 2021 at 18:57)</a>:</h4>
<p>my interpretation of the doc is that i should expect <code>y</code> to be <code>&amp;A</code>, not <code>A</code></p>



<a name="239642195"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/primitive%20reference%20%28Clone%29%20doc%20wrong%3F/near/239642195" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/primitive.20reference.20(Clone).20doc.20wrong.3F.html#239642195">(May 20 2021 at 18:58)</a>:</h4>
<p>if i change it to <code>_z: ()</code>, i get this:</p>
<div class="codehilite"><pre><span></span><code>error[E0308]: mismatched types
 --&gt; src/main.rs:7:18
  |
7 |     let _z: () = y.clone();
  |             --   ^^^^^^^^^ expected `()`, found struct `A`
  |             |
  |             expected due to this
</code></pre></div>



<a name="239642303"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/primitive%20reference%20%28Clone%29%20doc%20wrong%3F/near/239642303" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/primitive.20reference.20(Clone).20doc.20wrong.3F.html#239642303">(May 20 2021 at 18:59)</a>:</h4>
<p>i meant that i should expect <code>y.clone()</code> to be <code>&amp;A</code>, not <code>A</code>, according to the doc</p>



<a name="239642553"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/primitive%20reference%20%28Clone%29%20doc%20wrong%3F/near/239642553" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/primitive.20reference.20(Clone).20doc.20wrong.3F.html#239642553">(May 20 2021 at 19:00)</a>:</h4>
<p>if i wanted to clone the ref of type<code>&amp;A</code>, i'd have to use <code>(&amp;y).clone()</code></p>



<a name="239642687"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/primitive%20reference%20%28Clone%29%20doc%20wrong%3F/near/239642687" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Giacomo Stevanato <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/primitive.20reference.20(Clone).20doc.20wrong.3F.html#239642687">(May 20 2021 at 19:01)</a>:</h4>
<p>The doc doesn't say that the implementation of <code>Clone</code> for references bypasses autoderef</p>



<a name="239642962"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/primitive%20reference%20%28Clone%29%20doc%20wrong%3F/near/239642962" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/primitive.20reference.20(Clone).20doc.20wrong.3F.html#239642962">(May 20 2021 at 19:03)</a>:</h4>
<blockquote>
<p>The following traits are implemented for all &amp;T, regardless of the type of its referent:<br>
…<br>
Clone (Note that this will not defer to T’s Clone implementation if it exists!)</p>
</blockquote>
<p>i can interpret that as saying that if <code>y: &amp;T</code>, then <code>y.clone()</code> should clone the ref, not the referent of type<code>T</code></p>



<a name="239643121"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/primitive%20reference%20%28Clone%29%20doc%20wrong%3F/near/239643121" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Giacomo Stevanato <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/primitive.20reference.20(Clone).20doc.20wrong.3F.html#239643121">(May 20 2021 at 19:04)</a>:</h4>
<p>No, it means that if you're calling <code>&lt;&amp;T&gt;::clone(&amp;y)</code> then this won't defer to <code>T::clone</code></p>



<a name="239643152"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/primitive%20reference%20%28Clone%29%20doc%20wrong%3F/near/239643152" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/primitive.20reference.20(Clone).20doc.20wrong.3F.html#239643152">(May 20 2021 at 19:05)</a>:</h4>
<p>more importantly, if <code>y: &amp;T</code>, then <code>y.clone()</code> gives me either <code>T</code> or <code>&amp;T</code> depending on whether or not <code>T</code> implements <code>Clone</code></p>



<a name="239643603"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/primitive%20reference%20%28Clone%29%20doc%20wrong%3F/near/239643603" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Giacomo Stevanato <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/primitive.20reference.20(Clone).20doc.20wrong.3F.html#239643603">(May 20 2021 at 19:08)</a>:</h4>
<p>That's just how autoderef works. If <code>T</code> doesn't implement <code>Clone</code> then it won't find <code>T::clone</code>, proceeds to autoderef and finds <code>&lt;&amp;T&gt;::clone</code> that takes an <code>&amp;&amp;T</code>. If instead <code>T</code> implements <code>Clone</code> then the compiler istantly finds <code>T::clone</code> that takes an <code>&amp;T</code>, which is the type of <code>y</code>.</p>



<a name="239643664"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/primitive%20reference%20%28Clone%29%20doc%20wrong%3F/near/239643664" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Giacomo Stevanato <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/primitive.20reference.20(Clone).20doc.20wrong.3F.html#239643664">(May 20 2021 at 19:08)</a>:</h4>
<p>This applies to any trait</p>



<a name="239643715"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/primitive%20reference%20%28Clone%29%20doc%20wrong%3F/near/239643715" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/primitive.20reference.20(Clone).20doc.20wrong.3F.html#239643715">(May 20 2021 at 19:08)</a>:</h4>
<p><span class="user-mention silent" data-user-id="338379">Giacomo Stevanato</span> <a href="#narrow/stream/219381-t-libs/topic/primitive.20reference.20.28Clone.29.20doc.20wrong.3F/near/239643121">said</a>:</p>
<blockquote>
<p>No, it means that if you're calling <code>&lt;&amp;T&gt;::clone(&amp;y)</code> then this won't defer to <code>T::clone</code></p>
</blockquote>
<p>i'm not sure i understand why someone would expect the deferring to <code>T::clone</code> if attempting to clone a ref to <code>T</code></p>



<a name="239643829"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/primitive%20reference%20%28Clone%29%20doc%20wrong%3F/near/239643829" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Giacomo Stevanato <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/primitive.20reference.20(Clone).20doc.20wrong.3F.html#239643829">(May 20 2021 at 19:09)</a>:</h4>
<p>I don't know, but that's what the documentation is warning about</p>



<a name="239644166"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/primitive%20reference%20%28Clone%29%20doc%20wrong%3F/near/239644166" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/primitive.20reference.20(Clone).20doc.20wrong.3F.html#239644166">(May 20 2021 at 19:12)</a>:</h4>
<p><span class="user-mention silent" data-user-id="338379">Giacomo Stevanato</span> <a href="#narrow/stream/219381-t-libs/topic/primitive.20reference.20.28Clone.29.20doc.20wrong.3F/near/239643603">said</a>:</p>
<blockquote>
<p>That's just how autoderef works. If <code>T</code> doesn't implement <code>Clone</code> then it won't find <code>T::clone</code>, proceeds to autoderef and finds <code>&lt;&amp;T&gt;::clone</code> that takes an <code>&amp;&amp;T</code>. If instead <code>T</code> implements <code>Clone</code> then the compiler istantly finds <code>T::clone</code> that takes an <code>&amp;T</code>, which is the type of <code>y</code>.</p>
</blockquote>
<p>you understand this. i understand this now because i've spent quite some time staring at docs about method calls. but it was surprising behavior to me before, and i think it's likely to confuse newcomers</p>



<a name="239644804"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/primitive%20reference%20%28Clone%29%20doc%20wrong%3F/near/239644804" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Giacomo Stevanato <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/primitive.20reference.20(Clone).20doc.20wrong.3F.html#239644804">(May 20 2021 at 19:17)</a>:</h4>
<p>Autoderef is a bit complicated, but it allows to avoid writing so many <code>&amp;</code>s. Usually you shouldn't worry about it, just remember that if a method that takes <code>&amp;self</code> exists for both <code>T</code> and <code>&amp;T</code> then calling it on a variable of type <code>t: &amp;T</code> will call the implementation for <code>T</code>. In those cases you should consider writing the explicit form (<code>T::method(t)</code> vs <code>&lt;&amp;T&gt;::method(&amp;t)</code>).</p>
<p>There's also a nice answer on stackoverflow that explains autoderef, you might find it interesting <a href="https://stackoverflow.com/questions/28519997/what-are-rusts-exact-auto-dereferencing-rules">https://stackoverflow.com/questions/28519997/what-are-rusts-exact-auto-dereferencing-rules</a></p>



<a name="239646016"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/primitive%20reference%20%28Clone%29%20doc%20wrong%3F/near/239646016" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/primitive.20reference.20(Clone).20doc.20wrong.3F.html#239646016">(May 20 2021 at 19:26)</a>:</h4>
<p>yeah, autoderef/autoref is a great convenience and has benefits for ergonomics. it also produces surprising behavior that tripped me up, and i think we should figure out a way to document that better. the warning about <code>Clone</code> does imply that someone else ran into this sort of problem before (and i've seen it cause confusion for other people on Discord)</p>



<a name="239646751"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/primitive%20reference%20%28Clone%29%20doc%20wrong%3F/near/239646751" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/primitive.20reference.20(Clone).20doc.20wrong.3F.html#239646751">(May 20 2021 at 19:32)</a>:</h4>
<p>clippy helps here with a lint that's an error by default:</p>
<div class="codehilite" data-code-language="Text only"><pre><span></span><code>error: using `clone` on a double-reference; this will copy the reference of type `&amp;main::B` instead of cloning the inner type
  --&gt; src/main.rs:14:18
   |
14 |     let _z: &amp;B = y.clone();
   |                  ^^^^^^^^^
   |
   = note: `#[deny(clippy::clone_double_ref)]` on by default
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#clone_double_ref
help: try dereferencing it
   |
14 |     let _z: &amp;B = &amp;(*y).clone();
   |                  ^^^^^^^^^^^^^
help: or try being explicit if you are sure, that you want to clone a reference
   |
14 |     let _z: &amp;B = &lt;&amp;main::B&gt;::clone(y);
   |                  ^^^^^^^^^^^^^^^^^^^^
</code></pre></div>



<a name="239646782"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/primitive%20reference%20%28Clone%29%20doc%20wrong%3F/near/239646782" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/primitive.20reference.20(Clone).20doc.20wrong.3F.html#239646782">(May 20 2021 at 19:32)</a>:</h4>
<p>explicitly cloning a ref seems unusual, especially when refs are all <code>Copy</code></p>



<a name="239646950"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/primitive%20reference%20%28Clone%29%20doc%20wrong%3F/near/239646950" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/primitive.20reference.20(Clone).20doc.20wrong.3F.html#239646950">(May 20 2021 at 19:33)</a>:</h4>
<p><code>clippy::clone_double_ref</code> is default-deny, and there's also <code>clippy::clone_on_copy</code> that's just a warning</p>



<a name="239647143"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/primitive%20reference%20%28Clone%29%20doc%20wrong%3F/near/239647143" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Giacomo Stevanato <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/primitive.20reference.20(Clone).20doc.20wrong.3F.html#239647143">(May 20 2021 at 19:35)</a>:</h4>
<p>By the way I'm not quite sure why that <code>Clone</code> warning is there. <a href="https://github.com/rust-lang/rust/pull/43560">https://github.com/rust-lang/rust/pull/43560</a> is the PR that added it with the rest of the <code>reference</code> docs and there's no discussion/thought about that</p>



<a name="239647901"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/primitive%20reference%20%28Clone%29%20doc%20wrong%3F/near/239647901" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/primitive.20reference.20(Clone).20doc.20wrong.3F.html#239647901">(May 20 2021 at 19:41)</a>:</h4>
<p>if anything, i think there should be a warning that if you're trying to clone a ref for some reason, that the presence of a <code>Clone</code> trait on the referent can make it tricky to do so</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>